package cn.thr.pethome.menu.service.impl;

import cn.thr.pethome.base.service.Impl.BaseServiceImpl;
import cn.thr.pethome.menu.domain.Menu;
import cn.thr.pethome.menu.mapper.MenuMapper;
import cn.thr.pethome.menu.service.IMenuService;
import cn.thr.pethome.util.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author thr
 * @since 2023-02-01
 */
@Service
public class MenuServiceImpl extends BaseServiceImpl<Menu> implements IMenuService {

    public static final  String MENU_LIST = "menuList";

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public List<Menu> findAll() {
        if( redisTemplate.opsForValue().get(MENU_LIST) == null){ //判断里面有没有值
            List<Menu> all= super.findAll();
            redisTemplate.opsForValue().set(MENU_LIST,all,1, TimeUnit.DAYS); //如果没有就设置进去
            return all;
        }else {
            return (List<Menu>)redisTemplate.opsForValue().get(MENU_LIST);
        }
    }

    @Override
    public List<Long> findMenuByRole(List<Long> roles) {
        return menuMapper.findMenuByRoleIds(roles);
    }

    @Override
    public List<Menu> findAllByparentId() {
        return menuMapper.findAllByparentId();
    }

    @Override
    public List<Menu> tree() {
        //先查询全部的数据 获取到所有的顶级
        List<Menu> all = menuMapper.findAll();
        List<Menu> collect = all.stream()
                .filter(menu -> menu.getParentId() == null)
                .collect(Collectors.toList());//stream()是一个流  filter 是过滤的意思
                //Collectors.toList() 将流中的所有元素导出到一个列表( List )中
        //查询全部，过滤出为null的 顶级  ，然后在导出到LIst



        //将子级放入父级里面去
        collect.forEach(collects->{
            all.stream().filter(menu -> menu.getParentId()!= null).forEach(menu -> {
                if (menu.getParentId() == collects.getId()){
                    collects.getChildren().add(menu);
                }
            });
        });

        // 拿到所有为 null 的顶级进行循环 再查询全部，ParentId不为null的过滤出来 再进行判断父级的和子级的ParentId 子级就添加到父级里面去
        return collect;
    }

    @Override
    public void add(Menu menu) {
        if(menu.getParentId() != null){
            if(menu.getName() == null){
                throw new BusinessException("菜单名不能为空");
            }
            if(menu.getComponent() == null){
                throw new BusinessException("组件路径不能为空");
            }
            if(menu.getUrl() == null){
                throw new BusinessException("访问URL不能为空");
            }
            if(menu.getIndex() == null){
                throw new BusinessException("排序不能为空");
            }
        }
        super.add(menu);
        redisTemplate.opsForValue().set(MENU_LIST,super.findAll(),1, TimeUnit.DAYS);
    }

    @Override
    public void update(Menu menu) {
        super.update(menu);
        redisTemplate.opsForValue().set(MENU_LIST,super.findAll(),1, TimeUnit.DAYS);
    }
}
